<?php

/**
 * Model的积累
 */
class G_Model {
    
}

/**
 * 缓存相关的操作
 * Enter description here ...
 * @author Administrator
 *
 */
abstract class G_Cache {

    static $_selfs = array(); //单例模式要用到
    protected $_redis;
    protected $_memcache;
    protected $_memcahced;

    public abstract function set($key, $val, $timeout = 0);

    public abstract function get($keys);

    public abstract function flush();

    public abstract function del($keys);

    private function __construct($conf) {
        $engine = strtolower($conf['engine']);
        if ($engine == 'memcache') {
            $this->_memcache = new Memcache();
            if (isset($conf['servers'])) {
                if (is_array($conf['servers'])) {
                    foreach ($conf['servers'] AS $key => $val) {
                        $this->_memcache->addserver($val['host'], isset($val['port']) ? $val['port'] : 11211, true, isset($val['weight']) ? $val['weight'] : null, isset($val['timeout']) ? $val['timeout'] : null);
                    }
                } else {
                    trigger_error("Memcache 服务器列表配置错误");
                }
            } else {
                if (isset($conf['host'])) {
                    if (isset($conf['port'])) {
                        if (isset($conf['timeout'])) {
                            $this->_memcache->connect($conf['host'], $conf['port'], $conf['timeout']);
                        } else {
                            $this->_memcache->connect($conf['host'], $conf['port']);
                        }
                    } else {
                        $this->_memcache->connect($conf['host']);
                    }
                } else {
                    trigger_error("没有配置memcache的服务器");
                }
            }
        } elseif ($engine == 'memcached') {
            $this->_memcached = new Memcached;
            //$this->_memcahced
            if (isset($conf['servers'])) {
                if (is_array($conf['servers'])) {
                    foreach ($conf['servers'] AS $key => $val) {
                        $this->_memcached->addserver($val['host'], isset($val['port']) ? $val['port'] : 11211, true, isset($val['weight']) ? $val['weight'] : null, isset($val['timeout']) ? $val['timeout'] : null);
                    }
                } else {
                    trigger_error("Memcache 服务器列表配置错误");
                }
            } else {
                if (isset($conf['host'])) {
                    if (isset($conf['port'])) {
                        if (isset($conf['timeout'])) {
                            $this->_memcached->connect($conf['host'], $conf['port'], $conf['timeout']);
                        } else {
                            $this->_memcached->connect($conf['host'], $conf['port']);
                        }
                    } else {
                        $this->_memcached->connect($conf['host']);
                    }
                } else {
                    trigger_error("没有配置memcache的服务器");
                }
            }
        } elseif ($engine == 'redis') {
            
        }
    }

    public static function singleton($conf) {
        $key = md5(print_r($conf, TRUE));
        if (isset(self::$_selfs[$key]) === false) {
            $objName = get_called_class();
            self::$_selfs[$key] = new $objName($conf);
        }
        return self::$_selfs[$key];
    }

    public static function factory($conf) {
        if (isset($conf['engine'])) {
            $engine = strtolower($conf['engine']);
            if ($engine == "apc") {
                if (function_exists('apc_add')) {
                    include G_FRAMEWORKSDIR . "cache" . DS . 'Apc.cache.php';
                    return ApcCache::singleton($conf);
                } else {
                    trigger_error("系统不支持APC缓存");
                }
            } elseif ($engine == 'memcache') {
                if (class_exists('Memcache')) {
                    include G_FRAMEWORKSDIR . "cache" . DS . 'Memcache.cache.php';
                    return MemcacheCache::singleton($conf);
                } else {
                    trigger_error("系统不支持Memcache缓存");
                }
            } elseif ($engine == 'memcached') {
                if (class_exists('Memcached')) {
                    include G_FRAMEWORKSDIR . "cache" . DS . 'Memcached.cache.php';
                    return MemcachedCache::singleton($conf);
                } else {
                    trigger_error("系统不支持Memcached缓存");
                }
            } elseif ($engine == 'redis') {
                if (class_exists("Redis")) {
                    include G_FRAMEWORKSDIR . "cache" . DS . 'Redis.cache.php';
                    return RedisCache::singleton($conf);
                } else {
                    trigger_error("系统不支持Redis缓存");
                }
            } elseif ($engine == 'wincache') {
                if (function_exists('wincache_fcache_fileinfo')) {
                    include G_FRAMEWORKSDIR . "cache" . DS . 'Wincache.cache.php';
                    return WincacheCache::singleton($conf);
                } else {
                    trigger_error("系统不支持Redis缓存");
                }
            } else {
                trigger_error("不支持的缓存类型" . $engine);
            }
        } else {
            trigger_error("缓存配置错误");
        }
    }

    public function setObj($key, $val, $timeout = 0) {
        return $this->set($key, serialize($value), $timeout);
    }

    public function getObj($keys) {
        $rs = $this->get($keys);
        if (is_array($rs)) {
            foreach ($rs AS $k => $v) {
                $rs[$k] = unserialize($v);
            }
        }
        return $rs;
    }

}

/**
 * Controller的积累
 */
class G_Controller {

    protected $_template_dir = "template_dir";
    protected $_view;
    protected $_vars = array();
    protected $_appconfig; //系统的配置信息

    function __construct($framework) {
        require_once G_FRAMEWORKSDIR . 'template' . DS . 'smarty3' . DS . 'Smarty.class.php';
        $this->_appconfig = $framework->_config;
        $this->_view = new Smarty;
        switch ($this->_appconfig->getKey('template.resouse.type')) {
            case "db":
                break;
            case "file":
                $this->_view->setTemplateDir(APP_ROOT.$this->_appconfig->getKey('template.resouse.file.dir','templates/views'));
                $this->_view->setCompileDir(APP_ROOT.$this->_appconfig->getKey('template.compile.file.dir','templates/template_c'));
                break;
            default :
                trigger_error("模板配置错误，没有选择正确的资源类型");
                break;
        }
        switch ($this->_appconfig->getKey('template.cache.type')) {
            case "db":
                break;
            case "cache":
                break;
            case "file":
                break;
            default :
                $this->_view->caching = false;
                break;
        }
    }

    protected function _I($data, $k, $defv = '') {
        if (isset($data[$k])) {
            if (is_array($data[$k])) {
                $rs = array();
                foreach ($data[$k] AS $key => $val) {
                    $rs[$key] = $this->_I($data[$k], $key);
                }
                return $rs;
            } else {
                if (get_magic_quotes_gpc()) {
                    return addcslashes(trim($data[$k]));
                } else {
                    return trim($data[$k]);
                }
            }
        }
        return $defv;
    }

    protected function _get($key, $def = '') {
        return $this->_I($_GET, $defv);
    }

    protected function _post($key, $def = '') {
        return $this->_I($_POST, $defv);
    }

    protected function _cookie($key, $defv = '') {
        return $this->_I($_COOKIE, $defv);
    }

    protected function _req($key, $defv = '') {
        return $this->_I($_REQUEST, $defv);
    }

    /**
     * 向模板中设置变量
     */
    protected function assign($k, $v) {
        $this->_view->assign($k, $v);
    }

    protected function fetch($tpl = null) {
        if(!$tpl){
            $app = GHF::init();
            $tpl = sprintf("%s/%s.tpl",$app->_controller,$app->_action);
        }
        return $this->_view->fetch($tpl);
    }

    protected function display($tpl = null) {
        echo $this->fetch($tpl);
    }

    /**
     * 加载model
     */
    protected function model($name) {
        
    }

    protected function isAjax() {
        
    }

    protected function isPost() {
        return strtoupper($_SERVER["REQUEST_METHOD"]) == 'POST';
    }

    protected function _ip() {
        return $_SERVER["REMOTE_ADDR"];
    }

    public function __call($name, $args) {
        //页面
    }

}

/**
 * 获取配置数据
 */
class G_Config {

    static $_self;
    protected $_conf;

    private function __construct($filepath,$type,$section = "debug") {
        if($type == 'ini'){
            $this->_conf = parse_ini_file($filepath,true);
        }else{
            $this->_conf = include $filepath;
        }
        $this->_conf = $this->_conf[$section];
        //var_dump($this->_conf);
    }

    public static function load($filepath = null,$type = 'php',$section = "debug") {
        if (isset(self::$_self) === false) {
            self::$_self = new G_Config($filepath,$type,$section);
        }
        return self::$_self;
    }

    /**
     *  获取配置信息
     * */
    public function getKey($key, $def = '') {
        if(isset($this->_conf[$key])){
            return $this->_conf[$key];
        }
        $keys = explode('.', $key);
        $d = $this->_conf;
        foreach ($keys AS $k) {
            if (isset($d[$k])) {
                $d = $d[$k];
            } else {
                return $def;
            }
        }
        return $d;
    }

}

/**
 * 数据库连接
 */
abstract class G_DB {

    protected $_db_con;
    static $_selfs = array();

    public static function factory(G_Config $config) {
        
    }

    /**
     * 插入一条记录
     */
    public function insert($table, $data) {
        if ($data AND is_array($data)) {
            $keys = array_keys($data);
            $vals = array_values($data);
            foreach ($vals AS $k => $v) {
                $vales[$k] = $this->escape($v);
            }
            $SQL = sprintf("INSERT INTO %s(%s) VALUES('%s')", $table, implode(",", $keys), implode(',', $vals));
            if ($rs = $this->exec($SQL)) {
                return $this->getInsertId($rs);
            }
        }
        return false;
    }

    public function getRow($table, $where = null, $order = null) {
        $SQL = sprintf("SELECT * FROM %s %s %s %s", $table, $this->where($where), $this->order($order), $this->limit(1));
        $rs = $this->query($SQL);
        if ($rs) {
            $res = $this->fetch($rs);
            $this->free($rs);
            return $res;
        }
        return null;
    }

    public function getVar($table, $f, $where = null, $order = null) {
        $SQL = sprintf("SELECT $f FROM %s %s %s %s", $f, $table, $this->where($where), $this->order($order), $this->limit(1));
        $rs = $this->query($SQL);
        if ($rs) {
            $res = $this->fetch($rs);
            $this->free($rs);
            foreach ($res AS $val) {
                return $val;
            }
        }
        return null;
    }

    public function update($table, $data, $where = null) {
        $set = array();
        if ($data AND is_array($data)) {
            foreach ($data AS $k => $v) {
                $set[] = sprintf("%s='%s'", $k, $this->escape($v));
            }
            $SQL = sprintf("UPDATE %s SET %s %s", $table, implode(',', $set), $this->where($where));
            $rs = $this->exec($SQL);
            if ($rs) {
                return $this->getAffectedRows($rs);
            }
        }
        return false;
    }

    public function getResults($table, $where = null, $order = null, $limit = null) {
        $SQL = sprintf("SELECT * FROM %s %s %s %s", $table, $this->where($where), $this->order($order), $this->limit($limit));
        $rs = $this->query($SQL);
        if ($rs) {
            $res = array();
            while ($row = $this->fetch($rs)) {
                $res[] = $row;
            }
            $this->free($rs);
            return $res;
        }
        return null;
    }

    public function where($where = null) {
        if ($where) {
            if (is_array($where)) {
                $set = array();
                foreach ($where AS $k => $v) {
                    $set[] = sprintf("%s='%s'", $k, $this->escape($v));
                }
                return sprintf(" WHERE %s", implode(' AND ', $set));
            } elseif (is_string($where)) {
                return sprintf(" WHERE %s", $where);
            }
        }
        return '';
    }

    public function order($order = null) {
        if ($order) {
            //
        }
        return '';
    }

    public function limit($limit = null) {
        if ($limit) {
            if (is_numeric($limit)) {
                return sprintf(" LIMIT %d", $limit);
            } elseif (is_string($limit)) {
                return sprintf(" LIMIT %s", $limit);
            } elseif (is_array($limit)) {
                if (isset($limit[0])) {
                    if (isset($limit[1])) {
                        return sprintf(" LIMIT %d,%d", $limit[0], $limit[1]);
                    } else {
                        return sprintf(" LIMIT %d", $limit[0]);
                    }
                }
            }
        }
        return '';
    }

    public abstract function escape($string);

    public abstract function query($sql);

    public abstract function exec($sql);

    public abstract function getInsertId($rs);

    public abstract function getAffectedRows($rs);

    public abstract function fetch($rs);

    public abstract function free($rs);
}

/**
 * 图片处理
 * Enter description here ...
 * @author Administrator
 *
 */
abstract class G_Image {

    const INT = 1;
    const CHAR = 2;
    const INT_AND_CHAR = 3;
    const ZH = 4;

    public static function factory($engine) {
        
    }

    /**
     * 生成验证图片
     * Enter description here ...
     * @param unknown_type $code
     */
    public function code($type, $len = 4, $w = 100, $h = 30) {
        $code = "";
        if ($type == self::ZH) {
            $str = "大小多少高矮胖瘦水火尽木土个十百千万一二三四五六七八九十老又有飞机苹果番茄香蕉乒乓球篮组班级办证更红洪非费税";
            $strlen = mb_strlen($str) - 1;
            for ($i = 0; $i < $len; $i++) {
                $code .= mb_substr($str, rand(0, $strlen), 1);
            }
        } elseif ($type == self::CHAR) {
            $str = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
            $strlen = len($str) - 1;
            for ($i = 0; $i < $len; $i++) {
                $code .= substr($str, rand(0, $strlen), 1);
            }
        } elseif ($type == self::INT_AND_CHAR) {
            $str = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789";
            $strlen = len($str) - 1;
            for ($i = 0; $i < $len; $i++) {
                $code .= substr($str, rand(0, $strlen), 1);
            }
        } else {
            $fp = "%0{$len}d";
            $code = sprintf($fp, rand(0, pow(10, $len)));
        }
        if (session_start() == PHP_SESSION_ACTIVE) {
            $_SESSION['g_frame_code'] = $code;
        } else {
            setcookie('g_frame_code', md5($code), "/");
        }
        return $this->createCode($code, $w, $h);
    }

    /**
     * 验证图片
     * Enter description here ...
     * @param unknown_type $code
     */
    public function checkCode($code) {
        if (session_start() == PHP_SESSION_ACTIVE) {
            return isset($_SESSION['g_frame_code']) AND $_SESSION['g_frame_code'] == $code;
        } else {
            return isset($_COOKIE['g_frame_code']) AND $_COOKIE['g_frame_code'] == md5($code);
        }
    }

    /**
     * 设置图片大小
     * Enter description here ...
     * @param unknown_type $src
     * @param unknown_type $w
     * @param unknown_type $h
     */
    public abstract function resize($src, $w, $h);

    /**
     * 获取图片的切片
     * Enter description here ...
     * @param $src
     * @param $w
     * @param $h
     */
    public abstract function clip($src, $w, $h);

    /**
     * 生成验证码图片
     * Enter description here ...
     * @param unknown_type $code
     * @param unknown_type $w
     * @param unknown_type $h
     */
    public abstract function createCode($code, $w, $h);
}

abstract class G_Storage {

    protected $_con;

    public abstract function save($filename);

    public abstract function get($filename);

    public abstract function del($filename);
    //public abstract function list();
}